/*
 * Robomind.java
 * 
 * Descripcion: es la simulacion de robomind, se crea el mapa y el script en el contructor y se siguen las instrucciones
 * 		del script en el mapa cargado.
 * 
 * Integrantes:
 * 		Jennifer Valdez      10189
 * 		Gustavo Sanchez      10313
 *      Sergio Molina        10256
 *      
 * Fecha de entrega: 11 de agosto de 2011
 * 
 */

import javax.microedition.lcdui.*;

// extiende de canvas para poder realizar los cuadros
public class Robomind extends Canvas {
        

        //atributos
        private int ancho;
        private int largo;
        private int posx;
        private int posy;
        private boolean pintar;
        private int coloractual;
        private String script;
        
        // variables
        int[][] terreno = new int[10][10]; //matriz del mapa
        int cont = 0;
        int hcuadro;	
        int wcuadro;
        String codigo;
        
        //Constructor: inicializa las variables para el Robomind
        // 		los parametros son el codigo que debe ejecutar y el mapa que debe implementar
        public Robomind(String codigo, String cod){
                this.setFullScreenMode(false);  // se establece que no ocupe la pantalla completa
                script=cod;						// el script se inicializa con el parametro 
                ancho = this.getWidth();		// se toman las medidas de la pantalla
                largo = this.getHeight();
                hcuadro = largo/10;				// se calculan las proporciones de cada cuadro 
                wcuadro = ancho/10;
                posx = 0;						// la posicion inicial del robot
                posy = 9;
                pintar=false;					// al inicio el robot no pinta
                coloractual=3;
                for (int j=0; j<10; j++)		// se inicializa la matriz del mapa
                        for (int i=0; i<10; i++){
                        	try{
                                terreno[i][j]=codigo.charAt(cont)-48;	// se coloca lo indicado por el usuario
                                cont++;
                        	}
                            catch( StringIndexOutOfBoundsException e){ // se llena lo faltante con espacios vacios
                            	terreno[i][j]=1;
                                cont++;
                            }
                        }
                terreno[0][9]=1;		// la posicion inicial siempre esta vacia
        }
               
        // paint: pinta cada vez que es llamado 
        protected void paint(Graphics arg) {
            for (int j=0; j<10; j++)		//recorre la matriz del mapa
                for (int i=0; i<10; i++){
            		switch(terreno[i][j]){
            			case 1:  // si es espacio en blanco
            				arg.setColor(255,255,255);
            			break;
            			case 2:  // si es obstaculo
            				arg.setColor(87, 87, 87);
            			break;
            			case 3:  //rojo
            				arg.setColor(255, 0 , 0);
            			break;
            			case 4: //amarillo
            				arg.setColor(255,255,0);
            			break;
            			case 5: //azul
            				arg.setColor(0,0,255);
            			break;
            			case 6: // verde
            				arg.setColor(0,100,0);
            			break;
            			default:  // espacio en blanco
            				arg.setColor(255,255,255);
            			break;       				
            		}
            		// se hace el cuadrado pintado y los bordes de netro
                    arg.fillRect(i*wcuadro, j*hcuadro, wcuadro, hcuadro);
                    arg.setColor(0,0,0);
                    arg.drawRect(i*wcuadro, j*hcuadro, wcuadro, hcuadro);

                    // de color verde limon se dibuja el robot
                    arg.setColor(0, 255, 0);
                    arg.fillRoundRect((posx*wcuadro)+(wcuadro/3), posy*hcuadro, wcuadro/2, hcuadro/2, 40, 40);
                    arg.fillRect(posx*wcuadro, (posy*hcuadro)+(hcuadro/2), wcuadro, hcuadro/2);
                }           
        }

   //getposy: devuelve un entero especificando la posicion en y del robot     
   public int getposy(){
	   return posy;
   }
   
   //getposx: devuelve un entero especificando la posicion en x del robot
   public int getposx(){
	   return posx;
   }
   
   //gecoloractual: devuelve un entero que especifica que color debe pintar el robot
   public int getcoloractual(){
	   return coloractual;
   }
        
   // keyPressed es ejecutado al precionarse una tecla
   protected void keyPressed(int keyC){
         
	   super.keyPressed(keyC);  // se inicializa el keyPressed de la clase madre
         
         switch(keyC){
     		case KEY_NUM1:  // si presiono el 1 deja o empieza a pintar
     			pintar =! pintar;
     		break;
     		case KEY_NUM3: // cambia de color
     			cambiarcolor();
     		break;
            case KEY_NUM2: // avanza hacia adelante
                    arriba();
            break;
            case KEY_NUM8: //hacia atras
                    abajo();
            break;
            case KEY_NUM6: // cruza a derecha
                    derecha();
            break;
            case KEY_NUM4:  //cruza  a izquierda
                    izquierda();
            break;
            case KEY_NUM5:  // ejecuta el codigo cargado por el usuario
                    lector(script);
            break;  
         }
         repaint();     // vuelve a pintar toda la pantalla
   }
   
   //lector: ejecutar el codigo introducido por el usuario por medio de Thread para ver animacion
   public void lector(String code){
	   Hilo hilo = new Hilo();
	   codigo = code;
	   hilo.start();
   }
  
   
   //arriba: avanza hacia arriba 
   //	pre: arriba debe haber espacio libre
   //	post: avanzo hazia arriba
   public void arriba(){
	   if(posy != 0)
           if(terreno[posx][posy-1] != 2)
           {
               if(pintar)  // si debe pintar modifica el fondo del cuadro donde se encuentra
            	   terreno[posx][posy]=coloractual;
               posy--;  //cambia la posicion del robot
           }           
   }
   
   //abajo: se mueve hacia abajo
   //	pre: abajo debe ser un espacio libre
   //	post; se movio hacia abajo
   protected void abajo(){
       if(posy != 9)
           if(terreno[posx][posy+1]!=2)
           {
               if(pintar) // si debe pintar modifica el color del cuadro
            	   terreno[posx][posy]=coloractual; 
               posy++;  //modifica la posicion del robot
           }        
   }
   
   // izquierda: se mueve hacia la izquierda
   //	pre: la izquierda debe ser un espacio vacio
   //	post: el robot se mueve hacia la izquierda
   protected void izquierda(){
       if(posx != 0)
           if(terreno[posx-1][posy] != 2)
           {
               if(pintar)  // si debe pintar modifica el color del fondo
                       terreno[posx][posy]=coloractual;
               posx--;  //modifica la posicion del robot
           }
   }
   
   // derecha: se mueve hacia la derecha
   //	pre: la derecha debe ser un espacio vacio
   //	post: el robot se mueve hacia la derecha
   protected void derecha(){
           if(posx != 9)
               if(terreno[posx+1][posy]!=2)
               {
                   if(pintar)  // si debe pintar modifica el color del fondo
                	   terreno[posx][posy]=coloractual;
                   posx++;  //modifica la posicion del robot
               }
           
   }
   
   // cambiacolor: modifica el color con el que va pintando el robot
   protected void cambiarcolor(){
	   coloractual = coloractual == 6 ? 3 : coloractual+1;
   }
   
   //Hilo: clase que extiende de Tread para poder realizar las animaciones en los movimientos
   public class Hilo extends Thread{
	   public void run(){
		   for(int i=0; i<codigo.length(); i++){
               try{
            	   Hilo.sleep(200); // espera 200 milisegundos
               }catch(Exception e){}
               switch(codigo.charAt(i)-48){  //evalua el codigo 
                            case 2: //va hacia arriba
                            	arriba();
                            break;
                            case 8: //hacia abajo
                            	abajo();
                            break;
                            case 4: //hacia la izquierda
                                izquierda();
                            break;
                            case 6:  //hacia la derecha
                                derecha();
                            break;
                            case 1: // cambia el estado de pintar
                                pintar=!pintar;
                            break;
                            case 3:  //modifica el color del fondo al momento de pintar
                            	cambiarcolor();
                            break;
               }
               repaint(); // se vuelve a pintar la pantalla
		   }
	   }
   }
}